module memoryAlloctor (
    input wire clk,
    input wire rst,
    output reg write_padding_out,                      //写填充使能                   
    output reg write_en_out,                           //写使能
    output reg [14:0] write_address_out,               //写地址
    output reg [31:0] write_data_out,                  //写内容
);
    reg [1:0] write_state;

    always @(posedge clk) begin
        if (rst) begin
            write_state <= 2'b00;
            write_padding_out <= 0;
            write_en_out <= 0;
        end
    end

    always @(posedge clk) begin
        //收到入队成功信号后，拉低自身的入队信号
        if (enqueue_en && (enqueue_sucess & enqueue_port)>0) begin
            enqueue_en <= 0;
            enqueue_priority <= 0;
            enqueue_port <= 0;
        end
    end

    always @(posedge clk) begin
        if (write_state == 2'b01) begin
            manager_write_ready <= 0;
        end
    end

    //读状态转换逻辑
    always @(posedge clk) begin
        if (write_state == 2'b00 && write_en && ram_pick) begin
            write_state <= 2'b01;
            address_ready <= 1'b1;
            //暂存信息，后面会用到
            history_data_size <= write_size;
            history_data_port <= write_port;
            history_data_priority <= write_priority;
            history_data_index <= available_list[available_head];
            //从空闲队列中取出一块分配给数据包使用
            write_block <= available_list[available_head];
            write_address_counter <= 0;

            //空闲队列指针向后移动并取模，实现循环队列的功能
            if (available_head + 1 < 512) begin
                available_head <= available_head + 1;
            end
            else begin
                available_head <= 0;
            end
        end
        else begin
            address_ready <= 1'b0;
        end
    end

    //数据已经就绪，可以考虑将数据写入到RAM
    always @(posedge clk) begin
        if (write_state == 2'b01 && data_en_in) begin
            write_state <= 2'b10;
            write_en_out <= 1'b1;
            write_data_out <= data_in;
            write_address_out <= block_address[write_block] + write_address_counter;
            write_address_counter <= write_address_counter + 1;
        end
    end

    always @(posedge clk) begin
        if (write_state == 2'b10) begin
            write_en_out <= 1'b1;
            write_data_out <= data_in;
            write_address_out <= block_address[write_block] + write_address_counter;
            write_address_counter <= write_address_counter + 1;
            if (write_address_counter >= history_data_size) begin
                write_padding_out <= 1'b1;
            end
            else begin
                write_padding_out <= 1'b0;
            end
            //如果已经写满了一个内存块
            if (write_address_counter == 64) begin
                if (write_block == history_data_index) begin
                    //如果是第一块写完了，发出入队请求
                    enqueue_en <= 1'b1;
                    enqueue_port <= history_data_port;
                    enqueue_priority <= history_data_priority;
                    enqueue_value <= history_data_index;
                end

                write_address_counter <= 1;
                if (history_data_size - 64 < history_data_size) begin //数据已经不足一个完整快
                    //记录一下next和last标记
                    block_is_last[write_block] <= 1'b0;
                    block_next[write_block] <= available_list[available_head];
                    write_block <= available_list[available_head];
                    if (available_head + 1 < 512) begin
                        available_head <= available_head + 1;
                    end
                    else begin
                        available_head <= 0;
                    end
                    //size减小
                    history_data_size <= history_data_size - 64;
                end
                else begin
                    //如果已经是最后一个块，记录一下last
                    block_is_last[write_block] <= 1'b1;
                    //拉低自身的写入信号
                    write_state <= 2'b00;
                    address_ready <= 1'b0;
                    write_en_out <= 1'b0;
                    write_padding_out <= 1'b0;
                    manager_write_ready <= 1;
                end
            end
        end
    end

    assign manager_read_ready = ~read_state;
    //assign manager_write_ready = write_en==0 && work_state==2'b00; 

    //读逻辑
    always @(posedge clk) begin
        if (read_state == 1'b1 && read_address_counter < 64) begin
            read_en_out <= 1'b1;
            read_address_out <= block_address[read_block] + read_address_counter;
            read_address_counter <= read_address_counter + 1;
            //如果读到了一个块的最后一个字，则准备进行下一个块的读取
            if (read_address_counter == 63) begin
                read_address_counter <= 0;
                if (block_is_last[read_block]==1'b1) begin
                    //已经是最后一个块，不需要继续了
                    read_state <= 1'b0;
                end
                else if (block_is_last[read_block]==1'b0) begin
                    //根据next数组读取下一个块的内容
                    read_block <= block_next[read_block];
                    //计数器归零
                    read_address_counter <= 0;
                end
                //读取数据结束以后，将读取完毕的块号加入到空闲队列中
                available_list[available_tail] <= read_block;

                //空闲队列指针向后移动并取模，实现循环队列的功能
                if (available_tail + 1 < 512) begin
                    available_tail <= available_tail + 1;
                end
                else begin
                    available_tail <= 0;
                end
            end
        end
        else begin
            read_en_out <= 1'b0;
        end
    end

    //读状态转移
    always @(posedge clk) begin
        if (dequeue_en && read_state == 1'b0) begin
            //修改当前读状态
            read_state <= 1'b1;
            read_block <= dequeue_value;
            read_address_counter <= 0;
            dequeue_success <= 1'b1;
        end

        if (dequeue_success == 1'b1) begin
            dequeue_success <= 1'b0;
        end
    end
endmodule